package procsim;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class SignalsDialog extends JDialog implements ActionListener, KeyListener {
    private JPanel panel = new JPanel(new BorderLayout(4, 4));
    private JPanel panelCenter = new JPanel(new GridLayout());
    private JPanel panelWest = new JPanel(new GridLayout(0, 1, 0, 4));
    private JPanel panelSouth = new JPanel(new FlowLayout());
    private PaintSignals panelPaint = new PaintSignals(this);
    private JButton button = new JButton("Cancel");
    private JComboBox combo[] = new JComboBox[12];
    private int maxtakt=0;
    SignalsDialog(){
        setTitle("Signals");
        button.addActionListener(this);
        button.addKeyListener(this);
        for(int i=0; i<combo.length; i++){
            combo[i] = new JComboBox();
            combo[i].setEditable(false);
            combo[i].addItem("");
            ArrayList<String> names = SignalRegistry.getNames();
            Collections.sort(names);
            Iterator iter = names.iterator();
            while(iter.hasNext())
                combo[i].addItem((String)iter.next());
            combo[i].setSelectedIndex(0);
            combo[i].addActionListener(this);
            combo[i].addKeyListener(this);
            panelWest.add(combo[i]);
        }
        panelWest.add(new JLabel(""));
        panelCenter.add(panelPaint);
        panelSouth.add(button);
        panel.add(panelCenter, "Center");
        panel.add(panelWest, "West");
        panel.add(panelSouth, "South");
        setContentPane(panel);
        setSize(755, 435);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
    }

    public void update(Graphics2D g){
        for(int j = 0; j<12; j++){
            String name = (String)combo[j].getSelectedItem();
            if(!name.equals("")){
                ArrayList<Integer> values = SignalRegistry.getValues(name);
                drawSignal(values, j, g);
            }
        }
    }

    public void update(){
        panelPaint.repaint();
        int newxsize = (maxtakt-1)*31;
        panelPaint.setSize(new Dimension(newxsize>690 ? newxsize : 690, 370));
    }

    public void drawSignal(ArrayList<Integer> values, int i, Graphics2D g){
        Iterator iter = values.iterator();
        int x = 0;
        int previous = 0;
        int lasttakt = values.size();
        int takt = 0;
        if(lasttakt > 20) takt = lasttakt-21;
        else takt = 0;
        while(iter.hasNext() && takt!=lasttakt){
            g.setColor(Color.BLUE);
            if((Integer)iter.next() == 1){
                if(previous == 0) g.drawLine(x, 25+i*29, x, 5+i*29);
                g.drawLine(x, 5+i*29, x+30, 5+i*29);
                x+=30;
                previous = 1;
            }
            else {
                if(previous == 1) g.drawLine(x, 5+i*29, x, 25+i*29);
                g.drawLine(x, 25+i*29, x+30, 25+i*29);
                x+=30;
                previous = 0;
            }
            g.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 10.f, new float[]{5, 5, 5, 5}, 1.f));
            g.setColor(new Color(90, 90, 90));
            g.drawLine(x, 0, x, 360);
            g.setStroke(new BasicStroke(1));
            g.setColor(Color.BLACK);
            int shift = Integer.toString(takt).length();
            if(shift == 1) g.drawString(Integer.toString(takt), x-18, 360);
            else if(shift == 2) g.drawString(Integer.toString(takt), x-21, 360);
            else g.drawString(Integer.toString(takt), x-28, 360);
            takt++;
        }
        if(takt>maxtakt) maxtakt=takt;
     }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        for(int i=0; i<12; i++){
            if(e.getSource().equals(combo[i])){
                panelPaint.repaint();
                int newxsize = (maxtakt-1)*31;
                panelPaint.setSize(new Dimension(newxsize>690 ? newxsize : 690, 370));
            }
        }
        if(e.getActionCommand().equals("Cancel")){
            setVisible(false);
        }
    }

    @Override
    public void keyTyped(KeyEvent ke) { }
    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode()==KeyEvent.VK_ESCAPE || ke.getKeyCode()==KeyEvent.VK_ENTER)
            setVisible(false);
    }
    @Override
    public void keyReleased(KeyEvent ke) { }
}

class PaintSignals extends Canvas {
    private SignalsDialog dialog;
    public PaintSignals(SignalsDialog d){
        dialog = d;
        setBackground(Color.WHITE);
    }

    @Override
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        g2.setColor(Color.BLACK);
        dialog.update(g2);
    }
}
